
import cv2
import numpy

#3.7
if __name__ == '__main__' and False:
    """边缘检测"""
    img = cv2.imread("./lz-swk.jpeg", 0)
    cv2.imwrite("canny.jpg", cv2.Canny(img, 200, 300))
    cv2.imshow("canny", cv2.imread("canny.jpg"))
    cv2.waitKey()
    cv2.destroyAllWindows()

#3.8
if __name__ == "__main__" and False:
    """轮廓检测"""
    img = numpy.zeros((200, 200), dtype=numpy.uint8)
    img[50:150, 50:150] = 255

    ret, thresh = cv2.threshold(src=img, thresh=127, maxval=255, type=0, dst=None)
    contours, hierarchy = cv2.findContours(image=thresh, mode=cv2.RETR_TREE, method=cv2.CHAIN_APPROX_SIMPLE)
    color = cv2.cvtColor(src=img, code=cv2.COLOR_GRAY2BGR)
    img = cv2.drawContours(image=color, contours=contours, contourIdx=-1, color=(0, 255, 0), thickness=2)
    cv2.imshow(winname="contours", mat=color)
    cv2.waitKey()
    cv2.destroyAllWindows()


# 3.9
if __name__ == "__main__" and False:
    """计算边界框、最小矩形区域和最小闭圆的轮廓"""

    # pyrDown: 先将图像进行高斯平滑，然后再进行降采样（将图像尺寸行和列方向缩减一半）
    img = cv2.pyrDown(cv2.imread("lz-swk.jpeg", flags=cv2.IMREAD_UNCHANGED))

    ret, thresh = cv2.threshold(src=cv2.cvtColor(img.copy(), cv2.COLOR_BGR2GRAY), thresh=127, maxval=255, type=cv2.THRESH_BINARY)

    contours, hierarchy = cv2.findContours(image=thresh, mode=cv2.RETR_TREE, method=cv2.CHAIN_APPROX_SIMPLE)

    for c in contours:
        # find bounding box coordinates 查找边界框坐标
        x, y, w, h = cv2.boundingRect(c)
        cv2.rectangle(img, (x, y), (x+w, y+h), (0, 255, 0), thickness=2)

        # find minimum area.            查找最小矩形区域
        rect = cv2.minAreaRect(c)
        # calculate coordinates of the minimum area rectangle.
        box = cv2.boxPoints(rect)
        # normalize coordinates to integers
        box = numpy.int0(box)
        # draw contours
        cv2.drawContours(image=img, contours=[box], contourIdx=0, color=(0, 0, 255), thickness=3)

        # calculate center and radius of minimum enclosing circle.    计算最小闭合圆的圆心和半径
        (x, y), radius = cv2.minEnclosingCircle(c)
        # case to integers
        center = (int(x), int(y))
        radius = int(radius)
        # draw the circle
        img = cv2.circle(img, center=center, radius=radius, color=(0, 255, 0), thickness=1)

    cv2.drawContours(img, contours=contours, contourIdx=-1, color=(255, 0, 0), thickness=1)
    cv2.imshow("contours", img)
    cv2.waitKey()
    cv2.destroyAllWindows()

# 3.10 图轮廓与 Douglas-Peucker 算法
# 3.11.1 直线检测
if __name__ == "__main__" and False:
    img = cv2.imread("lz-swk.jpeg")
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    edges = cv2.Canny(image=img, threshold1=50, threshold2=120)
    minLineLength = 20
    maxLineGap = 5
    lines = cv2.HoughLinesP(edges, 1, numpy.pi/180, 100, minLineLength=minLineLength, maxLineGap=maxLineGap)
    for line in lines:
        for x1, y1, x2, y2 in line:
            cv2.line(img, (x1, y1), (x2, y2), color=(0, 255, 0), thickness=2)
    cv2.imshow("edges", edges)
    cv2.imshow("lines", img)
    cv2.waitKey()
    cv2.destroyAllWindows()

# 3.11.2 圆检测
if __name__ == "__main__":
    img = cv2.imread("lz-swk.jpeg")
    gray_img = cv2.cvtColor(img, code=cv2.COLOR_BGR2GRAY)
    median_blured_img = cv2.medianBlur(src=gray_img, ksize=5)
    c_img = cv2.cvtColor(median_blured_img, code=cv2.COLOR_GRAY2BGR)

    circles = cv2.HoughCircles(image=median_blured_img, method=cv2.HOUGH_GRADIENT, dp=1, minDist=120, circles=None, param1=100, param2=30, minRadius=0, maxRadius=0)
    circles = numpy.uint16(numpy.around(circles))

    for i in circles[0, :]:
        # draw the outer circle.
        cv2.circle(img, (i[0], i[1]), i[2], (0, 255, 0), 2)
        # draw the center of the circle.
        cv2.circle(img, (i[0], i[1]), 2, (0, 0, 255), 3)

    cv2.imwrite("circlrs.jpg", img)
    cv2.imshow("HoughCircles", img)
    cv2.waitKey()
    cv2.destroyAllWindows()

